﻿<template>
  <el-dialog v-drag :title = 'dialogSelectTitle' :visible.sync = 'dialogSelectVisible' width = '55%' :before-close = "handleClose"
  :close-on-press-escape = 'false' :close-on-click-modal = 'false'>
    <!-- 表格部分 -->
    <div class = 'page_tableContent'>
      <el-table :data = 'table.tableData' row-key = "functionno" :header-cell-class-name = 'handlemyclass' default-expand-all height = "400"
      style = 'width:100%' stripe border v-loading = 'loading' @select-all = "handleSelectAll" @select = 'handleSelect' ref = 'myTable'>
        <el-table-column :align = "index === 0 ? '' : 'center'" show-overflow-tooltip
        v-for = '(item, index) in table.tableColumn' :key = 'item.indexName' :label = 'item.text'>
          <template slot-scope = 'scope'>
            <span>{{scope.row[item.indexName]}}</span>
          </template>
        </el-table-column>
        <el-table-column type = "selection" :reserve-selection = "true" width = "55"></el-table-column>
      </el-table>
    </div>
    <span slot = "footer">
      <el-button type = 'info' @click = "$emit('giveUpFunc')">取 消</el-button>
      <el-button type = "primary" @click = 'handleSubmit'>确 定</el-button>
    </span>
  </el-dialog>
</template>

<script>
export default {
  props: ['funcDialog', 'roles'],
  data () {
    return {
      table: {
        tableData: [],
        tableColumn: [
          {
            text: '功能名称',
            indexName: 'functionname'
          },
          {
            text: '功能编号',
            indexName: 'functionno'
          }
        ]
      },
      dialogSelectVisible: false,
      dialogSelectTitle: '',
      loading: true,
      multipleSelection: null,
      totalFuncs: [],
      roleFuncs: []
    }
  },
  methods: {
    // 表头添加一个className
    handlemyclass (row) {
      if (row.column.label === '功能名称') {
        return 'uniqHead'
      }
    },
    // 获取该角色的功能
    getRoleInfo () {
      // 获取该角色下的功能和账号
      if (this.roles) {
        this.$get('/roleauth/' + this.roles).then(data => {
          if (data.data.result.code === 'success') {
            this.roleFuncs = data.data.result.data.function
            this.multipleSelection = []
            this.getFunctions()
          }
        }).catch(error => {
          console.log(error)
        })
      }
    },
    // 获取所有的功能
    getFunctions () {
      this.$get('/function').then((data) => {
        this.loading = false
        if (data.data.result) {
          this.totalFuncs = data.data.result
          // 只展示的功能权限---部分功能不展示,超级管理员展示所有
          let showData = []
          data.data.result.forEach(item => {
            if (this.$store.state.roleNo && this.$store.state.roleNo.indexOf('R999') !== -1) { // 超级管理员展示所有的
              showData.push(item)
            } else {
              // 不是超级管理员展示部分功能
              if (item.functionno.indexOf('F800') === -1 && item.functionno.indexOf('F002') === -1 && item.functionno !== 'F001001') {
                showData.push(item)
              }
            }
          })
          // 将数据结构转化为树形结构
          this.table.tableData = this.$toTree(showData, true)
          this.$refs.myTable.clearSelection()
          if (this.roleFuncs.length) {
            this.roleFuncs.forEach(val => {
              this.getSelectedFuns(this.table.tableData, val.functionno)
            })
          }
        }
      })
    },
    // 比较那些功能已经选中
    getSelectedFuns (funcData, funno) {
      if (funcData.length) {
        for (let i = 0; i < funcData.length; i++) {
          if (funcData[i].functionno === funno) {
            this.$refs.myTable.toggleRowSelection(funcData[i], true)
            if (this.multipleSelection.indexOf(funcData[i]) === -1) {
              this.multipleSelection.push(funcData[i])
            }
          } else {
            this.getSelectedFuns(funcData[i].children, funno)
          }
        }
      }
    },
    // 点击上部的X关闭弹窗时
    handleClose () {
      this.$emit('giveUpFunc')
    },
    // 点击确定按钮时
    handleSubmit () {
      this.loading = true
      this.$emit('sureFuncSelect', this.multipleSelection, this.totalFuncs)
    },
    // 全选时
    handleSelectAll (val) {
      if (val.length === this.totalFuncs.length || val.length === this.table.tableData.length) {
        val.forEach(item => {
          this.handleSelect(val, item)
        })
      } else {
        this.$refs.myTable.clearSelection()
        this.multipleSelection = []
      }
    },
    // 有选项事件时
    handleSelect (val, row) {
      // 点击是选中时
      if (val.length && val.indexOf(row) !== -1) {
        // 当有父元素时，要求也选中
        if (row.p_functionno) {
          let parentRow = this.getParents(row.p_functionno)
          if (!parentRow) {
            return
          }
          this.selectParent(parentRow)
          this.$refs.myTable.toggleRowSelection(parentRow, true)
          if (this.multipleSelection.indexOf(parentRow) === -1) {
            this.multipleSelection.push(parentRow)
          }
        }
        // 当有子元素时，子元素全选
        if (row.children.length) {
          row.children.forEach(val => {
            this.selectChild(val)
          })
        }
        // 本身需要选中
        if (this.multipleSelection.indexOf(row) === -1) {
          this.multipleSelection.push(row)
        }
      // 点击是取消选择时
      } else {
        // 当有父元素时，需判断该父元素下的子元素是否选中，如果没有选中，则该父元素取消选中
        if (row.p_functionno) {
          let count = 0
          let parentRow = this.getParents(row.p_functionno)
          if (!parentRow) {
            return
          }
          parentRow.children.forEach(vals => {
            if (val.indexOf(vals) === -1) {
              count++
            }
          })
          if (count === parentRow.children.length) {
            this.$refs.myTable.toggleRowSelection(parentRow, false)
            if (this.multipleSelection.length && this.multipleSelection.indexOf(parentRow) !== -1) {
              this.multipleSelection.splice(this.multipleSelection.indexOf(parentRow), 1)
            }
          }
          this.unSelectParent(this.multipleSelection, parentRow)
        }
        // 当有子元素时，子元素取消选中
        if (row.children.length) {
          row.children.forEach(val => {
            this.unSelectChild(val)
          })
        }
        // 本身需要取消选中
        if (this.multipleSelection.length && this.multipleSelection.indexOf(row) !== -1) {
          this.multipleSelection.splice(this.multipleSelection.indexOf(row), 1)
        }
      }
      // this.multipleSelection = val
    },
    // 获取该元素的父元素
    getParents (pCode) {
      let parentRow = ''
      let getParent = false
      if (this.table.tableData.length) {
        this.table.tableData.forEach(val => {
          if (val.functionno === pCode) { // 先判断该元素是不是需要获取的父元素,不是的话就在其子元素中寻找
            parentRow = val
            getParent = true
          } else {
            if (val.children.length) {
              let hadGet = this.getLastParent(pCode, val.children)
              if (hadGet) {
                parentRow = hadGet
                getParent = true
              }
            }
          }
        })
      }
      if (getParent) {
        return parentRow
      }
    },
    // 深层次的获取父元素
    getLastParent (pCode, childrenArray) {
      let parentRow = ''
      for (let i = 0; i < childrenArray.length; i++) {
        if (childrenArray[i].functionno === pCode) {
          parentRow = childrenArray[i]
          return parentRow
        } else {
          if (childrenArray[i].children.length) {
            parentRow = this.getLastParent(pCode, childrenArray[i].children)
            if (parentRow) {
              return parentRow
            }
          }
        }
      }
    },
    // 判断选中的选框是否有子菜单,有就全选
    selectChild (checkVal) {
      if (checkVal.children.length) {
        checkVal.children.forEach(val => {
          this.selectChild(val)
        })
      }
      this.$refs.myTable.toggleRowSelection(checkVal, true)
      if (this.multipleSelection.indexOf(checkVal) === -1) {
        this.multipleSelection.push(checkVal)
      }
    },
    // 判断取消的选框是否有子菜单,有就取消选择
    unSelectChild (checkVal) {
      if (checkVal.children.length) {
        checkVal.children.forEach(val => {
          this.unSelectChild(val)
        })
      }
      this.$refs.myTable.toggleRowSelection(checkVal, false)
      if (this.multipleSelection.length && this.multipleSelection.indexOf(checkVal) !== -1) {
        this.multipleSelection.splice(this.multipleSelection.indexOf(checkVal), 1)
      }
    },
    // 判断选中的选框是否有父菜单,有就选
    selectParent (parentRow) {
      if (parentRow.p_functionno) {
        let parentRows = this.getParents(parentRow.p_functionno)
        this.selectParent(parentRows)
        this.$refs.myTable.toggleRowSelection(parentRows, true)
        if (this.multipleSelection.indexOf(parentRows) === -1) {
          this.multipleSelection.push(parentRows)
        }
      }
    },
    // 判断取消的选框是否有父菜单,有就判断该父菜单下有没有选中的子菜单，没有就取消选中
    unSelectParent (selectedVal, parentRow) {
      if (parentRow.p_functionno) {
        let count = 0
        let parentRows = this.getParents(parentRow.p_functionno)
        parentRows.children.forEach(vals => {
          if (selectedVal.indexOf(vals) === -1) {
            count++
          }
        })
        if (count === parentRows.children.length) {
          this.$refs.myTable.toggleRowSelection(parentRows, false)
          if (this.multipleSelection.length && this.multipleSelection.indexOf(parentRows) !== -1) {
            this.multipleSelection.splice(this.multipleSelection.indexOf(parentRows), 1)
          }
        }
        this.unSelectParent(this.multipleSelection, parentRows)
      }
    }
  },
  watch: {
    funcDialog: {
      handler: function (val, oldVal) {
        this.dialogSelectVisible = val
        if (val) {
          // 将数据还原
          this.loading = true
          this.dialogSelectTitle = '功能授权'
          this.getRoleInfo()
        }
      },
      deep: true
    }
  }
}
</script>

<style scoped lang = 'scss'>
.table_toggleBtn {
  display: inline-block;
  width: 18px;
  height: 100%;
  margin-left: 20px;
  cursor: pointer;
  i {
    font-size: 18px;
    vertical-align: -1px;
  }
}
.table_trSpace {
  display: inline-block;
  width: 22px;
  height: 10px;
}
</style>
